home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-03-25 | 9.0 KB | 336 lines | [TEXT/CWIE] |
- // ===========================================================================
- // CNeuroSimPane.cp ©1996 Timo Eloranta
- // ===========================================================================
- // This class takes care of displaying the picture of the neural net.
- // Derived from the PowerPlant LView class.
-
- #include "CNeuroSimPane.h"
- #include "CNeuralNet.h"
- #include "NS_Utils.h"
-
- #include <UDrawingState.h>
- #include <UGWorld.h>
- #include <LWindow.h>
-
- const Uint16 kIconSize = 16; // Icon size in pixels
- const Uint16 kSquareSize = 21; // Grid square size in pixels
-
- const RGBColor kBlackRGB = { 0, 0, 0 }; // black
- const RGBColor kDarkRGB = { 0x0A05, 0x3E90, 0x05C1 }; // dark green
- const RGBColor kBrightRGB = { 0x1F74, 0xFFFF, 0x088A }; // bright green
-
- // ---------------------------------------------------------------------------
- // • CNeuroSimPane
- //
- // Called by: CNeuroSimPane::CreateNeuroSimPaneStream
- // ---------------------------------------------------------------------------
- // Constructor. We call the base class with the LStream object reference
- // and initialize some member attributes.
-
- CNeuroSimPane::CNeuroSimPane(
- LStream *inStream )
- : LView( inStream )
- {
- Rect theFrame;
- CalcLocalFrameRect( theFrame );
- mGWorld = new LGWorld( theFrame, 8 );
-
- if (! mGWorld )
- ::StopAlert( ALRT_Offscreen, NULL );
-
- mNet = NULL;
- mDrawingIsDirty = true;
- mBackgroundIsDirty = true;
- }
-
- // ---------------------------------------------------------------------------
- // • CreateNeuroSimPaneStream [static]
- //
- // Called by: CNeuroSimApp::InitNewNet (indirect call)
- // ---------------------------------------------------------------------------
- // Return a new NeuroSimPane object initialized using data from a Stream.
-
- CNeuroSimPane*
- CNeuroSimPane::CreateNeuroSimPaneStream(
- LStream *inStream)
- {
- return ( new CNeuroSimPane( inStream ) );
- }
-
- // ---------------------------------------------------------------------------
- // • ~CNeuroSimPane
- // ---------------------------------------------------------------------------
- // Destructor. Throw away the offscreen graphics world.
-
- CNeuroSimPane::~CNeuroSimPane()
- {
- if ( mGWorld )
- delete mGWorld;
- }
-
- // ---------------------------------------------------------------------------
- // • SetNet
- //
- // Called by: CNeuroSimApp::InitNewNet
- // ---------------------------------------------------------------------------
- // Connect the given net to this pane, init member attributes and
- // draw the net for the first time.
-
- void
- CNeuroSimPane::SetNet( CNeuralNet * inNet )
- {
- mNet = inNet;
- mGridSize = mNet -> GetNetSize();
-
- // Initializiation of mGridRect
-
- CalcLocalFrameRect( mGridRect );
- ::InsetRect( &mGridRect, 1, 1 );
-
- Int16 theGridWidth = mGridSize * kSquareSize;
- Int16 theInset = (mGridRect.right - theGridWidth - 2) / 2;
-
- ::InsetRect( &mGridRect, theInset, theInset);
-
- if ( theGridWidth % 2 ) {
- mGridRect.right++;
- mGridRect.bottom++;
- }
-
- // Initializiation of mOneOneRect
- //
- // We set the "one-one" rect to the [1,1] square of the matrix.
- // The size of this rect is set according to kIconSize.
-
- ::SetRect( &mOneOneRect,
- mGridRect.left + 1, // Left
- mGridRect.top + 1, // Top
- mGridRect.left + 1 + kIconSize, // Right
- mGridRect.top + 1 + kIconSize); // Bottom
-
- Int16 theOffset = (kSquareSize - kIconSize + 1) / 2;
-
- ::OffsetRect( &mOneOneRect, theOffset, theOffset);
-
- // Initializiation of center points
- //
- // Center points are used when drawing connections between neurons.
- // theOneOneXY is the point in the middle of the mOneOneRect. Only
- // one value is needed, because the X and Y coordinates are equal.
-
- Uint16 theOneOneXY = mGridRect.left + 1 + (kSquareSize / 2);
-
- mNet -> SetCenterPoints( theOneOneXY, kSquareSize );
-
- // Finally we draw the net for the first time
-
- DrawTheNet();
- }
-
- // ---------------------------------------------------------------------------
- // • InvalidateDrawing
- //
- // Called by: CNeuralNet::RequestDraw
- // ---------------------------------------------------------------------------
- // Force an immediate redraw of the net.
-
- inline void
- CNeuroSimPane::InvalidateDrawing()
- {
- mDrawingIsDirty = true;
- LView::Draw( NULL );
- }
-
- // ---------------------------------------------------------------------------
- // • DrawSelf
- //
- // Called by: LView::Draw
- // ---------------------------------------------------------------------------
- // Slam the net picture from the offscreen to the real screen...
-
- void
- CNeuroSimPane::DrawSelf()
- {
- Rect theFrame;
-
- // If the net has changed and we still haven't drawn it to
- // the offscreen, we better do it now...
-
- if ( mDrawingIsDirty ) {
- DrawTheNet();
- FocusDraw();
- }
-
- CalcLocalFrameRect( theFrame );
- StColorPenState::Normalize();
-
- if ( mGWorld )
- mGWorld -> CopyImage( GetMacPort(), theFrame );
- }
-
- // ---------------------------------------------------------------------------
- // • ClickSelf
- //
- // Called by: LPane::Click
- // ---------------------------------------------------------------------------
- // Respond to clicks in this view
-
- void
- CNeuroSimPane::ClickSelf(
- const SMouseDownEvent &inMouseDown)
- {
- Uint16 theCol, theRow;
- Boolean theOptionDown; // Option-key held down while clicking ?
-
- if ( PointToSquare( inMouseDown.whereLocal, theCol, theRow ) ) {
-
- theOptionDown = (inMouseDown.macEvent.modifiers & optionKey) != 0;
-
- CNeuronPtr theNeuron = mNet -> GetNeuron( theCol, theRow );
- theNeuron -> DoClickAction( theOptionDown );
- }
- }
-
- // ---------------------------------------------------------------------------
- // • PointToSquare
- //
- // Called by: CNeuroSimPane::ClickSelf
- // ---------------------------------------------------------------------------
- // Check if the given point is inside our net matrix.
- // If not, return FALSE. If it is, return TRUE and set the values of
- // outCol and outRow to point to the correct column and row.
-
- Boolean
- CNeuroSimPane::PointToSquare(
- const Point & inPoint,
- Uint16 & outCol,
- Uint16 & outRow )
- {
- if (! ::PtInRect( inPoint, &mGridRect ) )
- return false;
- else {
- outCol = ((inPoint.h - mGridRect.left - 1) / kSquareSize) + 1;
- if ( outCol > mGridSize )
- outCol = mGridSize;
-
- outRow = ((inPoint.v - mGridRect.top - 1) / kSquareSize) + 1;
- if ( outRow > mGridSize )
- outRow = mGridSize;
-
- return true;
- }
- }
-
- // ---------------------------------------------------------------------------
- // • DrawTheNet
- //
- // Called by: CNeuroSimPane::SetNet
- // CNeuroSimPane::DrawSelf
- // ---------------------------------------------------------------------------
- // Draw the net to our offscreen graphics world.
-
- void
- CNeuroSimPane::DrawTheNet()
- {
- if ( mGWorld ) {
-
- FocusDraw();
- StColorPenState theState;
-
- mGWorld -> BeginDrawing(); // Here we go...
-
- if ( mBackgroundIsDirty )
- DrawBackground();
-
- DrawConnections ();
- DrawNeurons ();
- DrawFrame();
-
- mGWorld -> EndDrawing(); // Done...
-
- Rect pRect = mGridRect;
- LocalToPortPoint( topLeft( pRect ) );
- LocalToPortPoint( botRight( pRect ) );
- InvalPortRect( &pRect ); // Force update
-
- mDrawingIsDirty = false; // No more "dirty"...
- }
- }
-
- // ---------------------------------------------------------------------------
- // • DrawBackground
- //
- // Called by: CNeuroSimPane::DrawTheNet
- // ---------------------------------------------------------------------------
- // Draw the background black and a dark green box around the entire grid.
-
- void
- CNeuroSimPane::DrawBackground()
- {
- Rect theFrame;
-
- CalcLocalFrameRect( theFrame );
- InsetRect( &theFrame, 1, 1); // A nice white frame...
-
- ::RGBBackColor( &kBlackRGB ); // Back color is black
- ::EraseRect( &theFrame);
-
- ::PenNormal();
- ::RGBForeColor( &kDarkRGB );
- ::FrameRect( &mGridRect); // Box around the entire grid
-
- mBackgroundIsDirty = false; // We only do this once!
- }
-
- // ---------------------------------------------------------------------------
- // • DrawConnections
- //
- // Called by: CNeuroSimPane::DrawTheNet
- // ---------------------------------------------------------------------------
- // Set the color to dark green and request the net to get all connections
- // between neurons to be drawn...
-
- void
- CNeuroSimPane::DrawConnections()
- {
- ::RGBForeColor( &kDarkRGB );
-
- mNet -> DrawConnections();
- }
-
- // ---------------------------------------------------------------------------
- // • DrawNeurons
- //
- // Called by: CNeuroSimPane::DrawTheNet
- // ---------------------------------------------------------------------------
- // Request the net to draw its neurons.
-
- void
- CNeuroSimPane::DrawNeurons()
- {
- mNet -> DrawNeurons( mOneOneRect, kSquareSize );
- }
-
- // ---------------------------------------------------------------------------
- // • DrawFrame
- //
- // Called by: CNeuroSimPane::DrawTheNet
- // ---------------------------------------------------------------------------
- // Draw a bright frame around the matrix.
-
- void
- CNeuroSimPane::DrawFrame()
- {
- Rect theInnerFrame = mGridRect;
-
- ::InsetRect( &theInnerFrame, 1, 1 );
- ::RGBForeColor( &kBrightRGB );
- ::FrameRect( &theInnerFrame);
-
- // Draw another bright box around the receptors (left side neurons)
-
- theInnerFrame.right = theInnerFrame.left + kSquareSize;
-
- ::FrameRect( &theInnerFrame);
- }
-